import os
import sys
from PyQt6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLabel, 
                           QComboBox, QFileDialog, QTableWidget, QTableWidgetItem, 
                           QHeaderView, QMessageBox, QLineEdit, QToolButton, QSplitter,
                           QApplication,QGroupBox)
from PyQt6.QtCore import Qt, pyqtSignal, QDir
from PyQt6.QtGui import QIcon
import pandas as pd
import subprocess

class BatchCreateWindow(QWidget):
    """批量创建文件的界面"""
    
    # 定义信号
    status_signal = pyqtSignal(str)
    closed = pyqtSignal()  # 窗口关闭信号
    
    def __init__(self, parent=None):
        super().__init__(parent)
        self.parent = parent
        self._excel_data = None  # 使用私有变量存储Excel数据
        self.output_dir = ""
        self.file_type = "文件夹"
        self.invalid_chars = ['/', '\\', ':', '*', '"', '<', '>', '|', '?']
        
        # 设置窗口属性
        self.setWindowTitle("批量创建")
        self.resize(800, 600)
        self.setStyleSheet("""
            QGroupBox {
                border: 1px solid #ccc;
                border-radius: 4px;
                margin-top: 10px;
                padding-top: 15px;
            }
            QGroupBox::title {
                subcontrol-origin: margin;
                left: 10px;
                padding: 0 3px;
            }
        """)
        
        # 调试信息
        print("批量创建窗口初始化")
        print(f"初始状态: excel_data={self._excel_data}, output_dir='{self.output_dir}'")
        
        self.init_ui()
        
    @property
    def excel_data(self):
        """Excel数据的getter方法"""
        return self._excel_data
        
    @excel_data.setter
    def excel_data(self, value):
        """Excel数据的setter方法，确保数据被正确设置"""
        print(f"\n==== 设置Excel数据 ====")
        print(f"设置前的Excel数据: {self._excel_data}")
        print(f"要设置的新数据类型: {type(value) if value is not None else 'None'}")
        
        if value is not None and isinstance(value, pd.DataFrame):
            print(f"设置新的DataFrame数据，形状: {value.shape}")
            self._excel_data = value.copy()  # 创建深拷贝
        else:
            print("设置Excel数据为None")
            self._excel_data = None
            
        print(f"设置后的Excel数据: {self._excel_data}")
        print(f"设置后的数据类型: {type(self._excel_data) if self._excel_data is not None else 'None'}")
        
    def init_ui(self):
        """初始化界面"""
        self.setWindowTitle("批量创建")
        print("初始化批量创建界面")
        
        # 创建主布局
        main_layout = QHBoxLayout(self)
        
        # 创建分割器
        splitter = QSplitter(Qt.Orientation.Horizontal)
        
        # 左侧操作窗体
        left_widget = QWidget()
        left_layout = QVBoxLayout(left_widget)
        
        # 导入Excel区域
        excel_group = QGroupBox("导入数据")
        excel_layout = QVBoxLayout(excel_group)
        
        # Excel导入按钮
        excel_button_layout = QVBoxLayout()
        self.excel_button = QPushButton("导入Excel")
        self.excel_button.setStyleSheet("background-color: #00B19D; color: white; padding: 8px;")
        self.excel_button.clicked.connect(self.import_excel)
        excel_button_layout.addWidget(self.excel_button)
        
        self.clear_button = QPushButton("清空列表")
        self.clear_button.setStyleSheet("padding: 8px;")
        self.clear_button.clicked.connect(self.clear_table)
        excel_button_layout.addWidget(self.clear_button)
        
        excel_layout.addLayout(excel_button_layout)
        
        # 添加查看文件名规范说明
        self.filename_rule_label = QLabel("注意：文件名不能包含 / \\ : * \" < > | ? 等特殊字符")
        self.filename_rule_label.setStyleSheet("color: red;")
        excel_layout.addWidget(self.filename_rule_label)
        
        left_layout.addWidget(excel_group)
        
        # 文件设置区域
        settings_group = QGroupBox("文件设置")
        settings_layout = QVBoxLayout(settings_group)
        
        # 文件类型选择
        settings_layout.addWidget(QLabel("文件类型"))
        self.file_type_combo = QComboBox()
        self.file_type_combo.addItems(["文件夹", "WORD", "EXCEL", "PDF", "PPT", "txt"])
        self.file_type_combo.currentTextChanged.connect(self.on_file_type_changed)
        settings_layout.addWidget(self.file_type_combo)
        
        # 输出目录选择
        settings_layout.addWidget(QLabel("输出目录"))
        output_dir_layout = QHBoxLayout()
        self.output_dir_edit = QLineEdit()
        self.output_dir_edit.setReadOnly(True)
        output_dir_layout.addWidget(self.output_dir_edit)
        
        self.browse_button = QToolButton()
        self.browse_button.setText("...")
        self.browse_button.clicked.connect(self.select_output_dir)
        output_dir_layout.addWidget(self.browse_button)
        
        self.open_dir_button = QPushButton("打开目录")
        self.open_dir_button.clicked.connect(self.open_output_dir)
        self.open_dir_button.setEnabled(False)
        output_dir_layout.addWidget(self.open_dir_button)
        
        settings_layout.addLayout(output_dir_layout)
        
        left_layout.addWidget(settings_group)
        
        # 执行按钮
        self.execute_button = QPushButton("立即执行")
        self.execute_button.setStyleSheet("background-color: #FF9F43; color: white; padding: 10px; font-weight: bold;")
        self.execute_button.clicked.connect(self.execute_batch_create)
        self.execute_button.setEnabled(False)
        left_layout.addWidget(self.execute_button)
        
        # 返回按钮
        self.back_button = QPushButton("返回主界面")
        self.back_button.setStyleSheet("padding: 8px;")
        self.back_button.clicked.connect(self.back_to_main)
        left_layout.addWidget(self.back_button)
        
        # 右侧预览窗体
        right_widget = QWidget()
        right_layout = QVBoxLayout(right_widget)
        
        # 添加表格
        self.table = QTableWidget(0, 3)  # 3列：文件名、状态、操作
        self.table.setHorizontalHeaderLabels(["名称", "状态", "操作"])
        self.table.horizontalHeader().setSectionResizeMode(0, QHeaderView.ResizeMode.Stretch)
        self.table.horizontalHeader().setSectionResizeMode(1, QHeaderView.ResizeMode.ResizeToContents)
        self.table.horizontalHeader().setSectionResizeMode(2, QHeaderView.ResizeMode.ResizeToContents)
        right_layout.addWidget(self.table)
        
        # 添加到分割器
        splitter.addWidget(left_widget)
        splitter.addWidget(right_widget)
        splitter.setSizes([200, 400])  # 设置初始大小
        
        # 添加到主布局
        main_layout.addWidget(splitter)
        
    def import_excel(self):
        """导入Excel文件"""
        print("\n==== 开始导入Excel ====")
        file_path, _ = QFileDialog.getOpenFileName(
            self, "选择Excel文件", "", "Excel Files (*.xlsx *.xls)"
        )
        
        if not file_path:
            print("用户取消了Excel文件选择")
            return
            
        try:
            print(f"正在导入Excel文件: {file_path}")  # 调试信息
            
            # 读取Excel文件
            df = pd.read_excel(file_path)
            
            # 检查是否有数据
            if df.empty:
                QMessageBox.warning(self, "警告", "Excel文件中没有数据！")
                print("Excel文件为空，没有数据")
                return
                
            # 检查是否有第一列
            if len(df.columns) < 1:
                QMessageBox.warning(self, "警告", "Excel文件格式不正确，需要至少一列数据！")
                print("Excel文件格式不正确，没有列")
                return
                
            # 打印数据预览
            print(f"Excel数据预览: \n{df.head()}")
            print(f"数据形状: {df.shape}")
            print(f"Excel列名: {df.columns.tolist()}")
            
            # 保存数据 - 确保创建DataFrame的深拷贝
            self.excel_data = df.copy()
            print(f"Excel数据已保存到self.excel_data，类型: {type(self.excel_data)}")
            print(f"保存后的数据形状: {self.excel_data.shape}")
            
            # 清空表格但不清除Excel数据
            self.table.setRowCount(0)
            self.table.repaint()
            QApplication.processEvents()
            
            # 填充表格
            self.populate_table()
            
            # 启用执行按钮
            self.update_execute_button()
            
            # 确认Excel数据状态
            print(f"导入后的Excel数据状态: {type(self.excel_data)}")
            print(f"导入后的Excel数据形状: {self.excel_data.shape if hasattr(self.excel_data, 'shape') else 'None'}")
            
            print(f"Excel文件导入完成：{file_path}")  # 调试信息
                
        except Exception as e:
            print(f"导入Excel出错: {str(e)}")  # 调试信息
            import traceback
            print(traceback.format_exc())  # 打印详细的错误堆栈
            QMessageBox.critical(self, "错误", f"导入Excel文件时出错：{str(e)}")
    
    def clear_table(self):
        """清空表格"""
        print("清空表格")
        self.table.setRowCount(0)
        # 不要在这里清空Excel数据，否则会导致数据丢失
        # self.excel_data = None  # 移除这行代码
        self.table.repaint()
        QApplication.processEvents()
    
    def populate_table(self):
        """填充表格"""
        print("\n==== 开始填充表格 ====")
        print(f"Excel数据: {self.excel_data}")
        
        if self.excel_data is None:
            print("Excel数据为None，无法填充表格")
            return
            
        if hasattr(self.excel_data, 'empty') and self.excel_data.empty:
            print("Excel数据为空DataFrame，无法填充表格")
            return
            
        # 打印更多信息以便调试
        print(f"Excel数据类型: {type(self.excel_data)}")
        print(f"Excel数据形状: {self.excel_data.shape if hasattr(self.excel_data, 'shape') else '未知'}")
        print(f"Excel数据列: {self.excel_data.columns.tolist() if hasattr(self.excel_data, 'columns') else '未知'}")
        print(f"Excel数据前5行: \n{self.excel_data.head() if hasattr(self.excel_data, 'head') else '未知'}")
        
        # 获取第一列数据作为文件名
        try:
            # 获取第一列数据，无论列名是什么
            first_column = self.excel_data.iloc[:, 0]
            file_names = first_column.astype(str).tolist()
            print(f"从Excel中读取到{len(file_names)}个文件名")
            print(f"文件名示例: {file_names[:3]}")
            
            # 设置表格行数
            self.table.setRowCount(len(file_names))
            
            # 填充表格
            for i, name in enumerate(file_names):
                # 文件名
                self.table.setItem(i, 0, QTableWidgetItem(name))
                
                # 检查文件名是否合法
                is_valid = self.is_valid_filename(name)
                
                # 状态
                status = "待操作" if is_valid else "文件名无效"
                status_item = QTableWidgetItem(status)
                if not is_valid:
                    status_item.setForeground(Qt.GlobalColor.red)
                self.table.setItem(i, 1, status_item)
                
                # 操作按钮
                delete_button = QPushButton("删除")
                delete_button.clicked.connect(lambda _, row=i: self.delete_row(row))
                self.table.setCellWidget(i, 2, delete_button)
            
            print(f"表格已填充完成，共{self.table.rowCount()}行")  # 调试信息
            
        except Exception as e:
            print(f"填充表格时出错: {str(e)}")
            import traceback
            print(traceback.format_exc())
        
        print(f"表格已填充完成，共{self.table.rowCount()}行")  # 调试信息
        
        # 强制刷新表格显示
        self.table.resizeColumnsToContents()
        self.table.resizeRowsToContents()
        self.table.repaint()
        
        # 确保表格在界面上可见
        QApplication.processEvents()
    
    def is_valid_filename(self, filename):
        """检查文件名是否合法"""
        if not filename or filename.strip() == "":
            return False
            
        for char in self.invalid_chars:
            if char in filename:
                return False
                
        return True
    
    def get_file_path(self, filename):
        """获取文件路径"""
        if not self.output_dir:
            # 如果没有输出目录，根据文件类型返回带扩展名的文件名
            if self.file_type == "文件夹":
                return filename
            elif self.file_type == "WORD":
                return f"{filename}.docx"
            elif self.file_type == "EXCEL":
                return f"{filename}.xlsx"
            elif self.file_type == "PDF":
                return f"{filename}.pdf"
            elif self.file_type == "PPT":
                return f"{filename}.pptx"
            elif self.file_type == "txt":
                return f"{filename}.txt"
            else:
                return filename
        else:
            # 如果有输出目录，返回完整路径
            if self.file_type == "文件夹":
                return os.path.join(self.output_dir, filename)
            elif self.file_type == "WORD":
                return os.path.join(self.output_dir, f"{filename}.docx")
            elif self.file_type == "EXCEL":
                return os.path.join(self.output_dir, f"{filename}.xlsx")
            elif self.file_type == "PDF":
                return os.path.join(self.output_dir, f"{filename}.pdf")
            elif self.file_type == "PPT":
                return os.path.join(self.output_dir, f"{filename}.pptx")
            elif self.file_type == "txt":
                return os.path.join(self.output_dir, f"{filename}.txt")
            else:
                return os.path.join(self.output_dir, filename)
    
    def delete_row(self, row):
        """删除表格行"""
        self.table.removeRow(row)
        
        # 更新行号
        for i in range(row, self.table.rowCount()):
            delete_button = self.table.cellWidget(i, 2)
            if delete_button:
                delete_button.clicked.disconnect()
                delete_button.clicked.connect(lambda _, r=i: self.delete_row(r))
        
        # 如果表格为空，禁用执行按钮
        if self.table.rowCount() == 0:
            self.execute_button.setEnabled(False)
        
        # 更新Excel数据
        if self.excel_data is not None and not self.excel_data.empty:
            self.excel_data = self.excel_data.drop(self.excel_data.index[row]).reset_index(drop=True)
    
    def on_file_type_changed(self, file_type):
        """文件类型改变时更新表格"""
        self.file_type = file_type
        self.update_table_paths()
    
    def update_table_paths(self):
        """更新表格中的路径（保留此方法以兼容现有代码，但不再更新表格中的路径列）"""
        # 由于已经移除了路径列，此方法不再需要更新表格
        pass
    
    def select_output_dir(self):
        """选择输出目录"""
        dir_path = QFileDialog.getExistingDirectory(self, "选择输出目录")
        if dir_path:
            print(f"正在设置输出目录: {dir_path}")  # 调试信息
            
            # 保存输出目录
            self.output_dir = dir_path
            self.output_dir_edit.setText(dir_path)
            self.open_dir_button.setEnabled(True)
            
            # 更新表格中的路径
            self.update_table_paths()
            
            # 检查Excel数据状态
            print(f"检查Excel数据: {self.excel_data}")
            if self.excel_data is None:
                print("警告: Excel数据为None，请先导入Excel文件")
            
            # 更新执行按钮状态
            self.update_execute_button()
            
            print(f"输出目录设置完成：{dir_path}")  # 调试信息
    
    def open_output_dir(self):
        """打开输出目录"""
        if not self.output_dir:
            return
            
        # 根据操作系统打开文件夹
        try:
            if sys.platform == 'win32':
                os.startfile(self.output_dir)
            elif sys.platform == 'darwin':  # macOS
                subprocess.run(['open', self.output_dir])
            else:  # Linux
                subprocess.run(['xdg-open', self.output_dir])
        except Exception as e:
            QMessageBox.critical(self, "错误", f"无法打开目录：{str(e)}")
    
    def execute_batch_create(self):
        """执行批量创建"""
        if not self.output_dir:
            QMessageBox.warning(self, "警告", "请先选择输出目录！")
            return
            
        if self.table.rowCount() == 0:
            QMessageBox.warning(self, "警告", "没有要创建的文件！")
            return
        
        print(f"开始执行批量创建，输出目录：{self.output_dir}")  # 调试信息
            
        # 检查是否有无效的文件名
        invalid_count = 0
        for i in range(self.table.rowCount()):
            status = self.table.item(i, 1).text()
            if status == "文件名无效":
                invalid_count += 1
                
        if invalid_count > 0:
            result = QMessageBox.question(
                self, "确认", f"有 {invalid_count} 个文件名无效，是否继续？",
                QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No
            )
            if result == QMessageBox.StandardButton.No:
                return
        
        # 创建文件
        success_count = 0
        fail_count = 0
        
        for i in range(self.table.rowCount()):
            filename = self.table.item(i, 0).text()
            file_path = self.get_file_path(filename)
            status = self.table.item(i, 1).text()
            
            # 跳过无效文件名
            if status == "文件名无效":
                continue
                
            try:
                if self.file_type == "文件夹":
                    os.makedirs(file_path, exist_ok=True)
                    success_count += 1
                    self.table.setItem(i, 1, QTableWidgetItem("已创建"))
                else:
                    # 创建文件
                    self.create_file(file_path)
                    success_count += 1
                    self.table.setItem(i, 1, QTableWidgetItem("已创建"))
            except Exception as e:
                fail_count += 1
                error_item = QTableWidgetItem(f"失败: {str(e)}")
                error_item.setForeground(Qt.GlobalColor.red)
                self.table.setItem(i, 1, error_item)
        
        # 显示结果
        QMessageBox.information(
            self, "完成", 
            f"批量创建完成！\n成功: {success_count}\n失败: {fail_count}"
        )
    
    def create_file(self, file_path):
        """创建文件"""
        file_ext = os.path.splitext(file_path)[1].lower()
        
        try:
            if file_ext == ".docx":
                try:
                    from docx import Document
                    doc = Document()
                    doc.add_paragraph("这是一个示例Word文档")
                    doc.save(file_path)
                except ImportError:
                    self.show_missing_dependency_warning("python-docx", file_path)
                    
            elif file_ext == ".xlsx":
                try:
                    import openpyxl
                    wb = openpyxl.Workbook()
                    ws = wb.active
                    ws['A1'] = "这是一个示例Excel工作表"
                    wb.save(file_path)
                except ImportError:
                    self.show_missing_dependency_warning("openpyxl", file_path)
                    
            elif file_ext == ".pdf":
                try:
                    from reportlab.pdfgen import canvas
                    c = canvas.Canvas(file_path)
                    c.drawString(100, 750, "这是一个示例PDF文档")
                    c.save()
                except ImportError:
                    self.show_missing_dependency_warning("reportlab", file_path)
                    
            elif file_ext == ".pptx":
                try:
                    from pptx import Presentation
                    prs = Presentation()
                    slide = prs.slides.add_slide(prs.slide_layouts[0])
                    title = slide.shapes.title
                    subtitle = slide.placeholders[1]
                    title.text = "示例演示文稿"
                    subtitle.text = "这是一个示例PPT文档"
                    prs.save(file_path)
                except ImportError:
                    self.show_missing_dependency_warning("python-pptx", file_path)
                    
            elif file_ext == ".txt":
                with open(file_path, 'w', encoding='utf-8') as f:
                    f.write("这是一个示例文本文件")
            else:
                with open(file_path, 'w', encoding='utf-8') as f:
                    f.write("")
                    
        except Exception as e:
            with open(file_path, 'w', encoding='utf-8') as f:
                f.write(f"创建文件时出错: {str(e)}")
                
    def show_missing_dependency_warning(self, package_name, file_path):
        """显示缺少依赖的警告"""
        warning_msg = f"缺少依赖: {package_name}\n请运行: pip install {package_name}"
        with open(file_path, 'w', encoding='utf-8') as f:
            f.write(warning_msg)
        QMessageBox.warning(self, "缺少依赖", 
                          f"需要安装 {package_name} 包来创建此类型文件\n\n请运行:\npip install {package_name}")
    
    def back_to_main(self):
        """返回主界面"""
        self.closed.emit()  # 发送关闭信号
        self.close()  # 关闭窗口
        
    def closeEvent(self, event):
        """重写关闭事件，确保窗口关闭时发出信号"""
        self.closed.emit()
        print("批量创建窗口已关闭")  # 调试信息
        super().closeEvent(event)
        
    def showEvent(self, event):
        """重写显示事件，确保窗口正确显示"""
        super().showEvent(event)
        print("批量创建窗口已显示")  # 调试信息
        self.activateWindow()  # 激活窗口
    
    def update_execute_button(self):
        """更新执行按钮状态"""
        # 检查条件
        has_excel_data = self.excel_data is not None and not self.excel_data.empty if hasattr(self.excel_data, 'empty') else self.excel_data is not None
        has_output_dir = self.output_dir != ""
        
        # 设置按钮状态
        should_enable = has_excel_data and has_output_dir
        self.execute_button.setEnabled(should_enable)
        
        # 打印详细的调试信息
        print(f"执行按钮状态检查:")
        print(f"  - Excel数据: {self.excel_data}")
        print(f"  - Excel数据类型: {type(self.excel_data)}")
        print(f"  - Excel数据存在: {has_excel_data}")
        print(f"  - 输出目录: '{self.output_dir}'")
        print(f"  - 输出目录存在: {has_output_dir}")
        print(f"  - 按钮应该启用: {should_enable}")
        print(f"  - 按钮当前状态: {self.execute_button.isEnabled()}")
        
        # 强制刷新按钮状态
        self.execute_button.repaint()
        QApplication.processEvents()